const log4js = require('log4js');
const path = require('path');
// log4js的输出级别6个: trace, debug, info, warn, error, fatal
const config = {
    "appenders": {
        "consoleout": {
            "type": "console"  // 日志
        },
        "reqLog": {
            "type": "dateFile",  // 输出文件类型   file: 输出文件[pattern,alwaysIncludePattern参数不生效]  datefile: [alwaysIncludePattern, daysToKeep, pattern]参数生效
            "filename": path.resolve(__dirname, '../../logs', "req"),
            "pattern": ".yyyy-MM-dd.log",  // 文件名字拼接规则
            "alwaysIncludePattern": true,  // 输出文件时是否添加 pattern
            "keepFileExt": true,  // 日志文件是否始终保持后缀（.log），默认为false
            "encoding": "utf-8",
            "daysToKeep": 30  // 文件有效期 单位（天）
        },
        "resLog": {
            "type": "dateFile",
            "filename": path.resolve(__dirname, '../../logs', "res"),
            "pattern": ".yyyy-MM-dd.log",
            "alwaysIncludePattern": true,
            "keepFileExt": true,
            "encoding": "utf-8",
            "daysToKeep": 30
        },
        "errLog": {
            "type": "dateFile",
            "filename": path.resolve(__dirname, '../../logs', "err"),
            "pattern": ".yyyy-MM-dd.log",
            "alwaysIncludePattern": true,
            "keepFileExt": true,
            "encoding": "utf-8",
            "daysToKeep": 30
        }
    },
    "categories": {
        "default": {
            "appenders": [
                "consoleout"
            ],
            "level": "debug"
        },
        "errLog": {
            "appenders": ["errLog"],
            "level": "error"
        },
        "resLog": {
            "appenders": ["resLog"],
            "level": "all"
        },
        "reqLog": {
            "appenders": ["reqLog"],
            "level": "all"
        }
    }
}
log4js.configure(config);

//getLogger参数取categories项,为空或者其他值取default默认项
// exports.getLogger = function (name) {
//     return log4js.getLogger(name || 'default')
// }
class CommonHandle {
    constructor(){}
    // 格式化请求日志
    static formatReqLog(ctx, time){
        let text = '------------request start------------'
        let method = ctx.method
        text += `request method:  ${method} \n request url: ${ctx.originalUrl } \n`

        if(method = 'GET'){
            text += `request data: ${JSON.stringify(ctx.query)} \n`
        }else{
            text += `request data: ${JSON.stringify(ctx.body)} \n`
        }
        text += `ctx all: ${JSON.stringify(ctx)}`
        return text
    }
    // 格式化相应日志
    static formatResLog(ctx,time){
        let text = '------------response start------------'
        text += `response result: ${JSON.stringify(ctx.response.body)} \n`

        text += `response all: ${JSON.stringify(ctx)} \n`

        text += `response time: ${time} \n`
        return text
    }
    // 格式化错误日志
    static formatErrorLog(ctx,error,time){
        let text = '------------error start------------'
        text += this.formatResLog(ctx,time)
        text += `error content: ${JSON.stringify(error)}`
        return text
    }
}

class HandleLogger extends CommonHandle{
    constructor(){
        super()
    }

    // 请求日志
    static reqLogger(ctx){
        log4js.getLogger('reqLog').info(this.formatReqLog(ctx));
    }

    // 相应日志
    static resLogger(ctx, time){
        log4js.getLogger('resLog').info(this.formatResLog(ctx,time))
    }

    // 错误日志
    static errorLogger(ctx, error, time){
        log4js.getLogger('errLog').info(this.formatErrorLog(ctx,error,time))
    }

}





module.exports = () => {
    return async (ctx,next) => {
        const url = ctx.url;
        let file = url.split('/').pop();
        if (file && file.split('.').length > 1) {
            await next();
        } else {
            const startTime = new Date();
            let period;
            try{
                // 请求日志
                HandleLogger.reqLogger(ctx)
                await next()
                period = new Date() - startTime
                // 响应日志
                HandleLogger.resLogger(ctx,period)
            }catch(err){
                period = new Date() - startTime
                // 错误日志
                HandleLogger.errorLogger(ctx, err, period)
            }
        }
        
    }
}
